package com.zlzlib.libftp;


import java.io.File;

import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferListener;

/**
 * @Desc:ftp的工具类
 * @Copyright:
 * @DateTime: 2021/2/25 17:03
 * @Author zlz
 * @Version 1.0
 */
public class FtpHelper {

    private volatile static FtpHelper instance = null;

    public static FtpHelper getInstance() {
        if (instance == null) {
            synchronized (FtpHelper.class) {
                if (instance == null) {
                    instance = new FtpHelper();
                }
            }
        }
        return instance;
    }

    private FtpHelper() {
    }


    private String ip;
    private int port;
    private String user;
    private String password;
    // 是否匿名访问
    private boolean anonymous = false;
    //读取文件端口范围
    private String portRange;
    //是否使用自定义端口,和portRange一起使用
    private boolean customPortRange = false;
    //超时时间
    private long timeOut = 10000;
    //编码格式
    private String charset = "utf-8";
    //传输方式
    private int type = FTPClient.TYPE_BINARY;

    /**
     * 初始化
     *
     * @param ip
     * @param port
     * @param user
     * @param password
     */
    public void init(String ip, int port, String user, String password) {
        this.ip = ip;
        this.port = port;
        this.user = user;
        this.password = password;
    }

    public void init(String ip, int port) {
        this.ip = ip;
        this.port = port;
        anonymous = true;
    }

    /**
     * 设置文件读取自定义端口
     *
     * @param portRange
     */
    public void setPortRange(String portRange) {
        this.portRange = portRange;
        customPortRange = true;
    }

    /**
     * 设置超时时间
     *
     * @param timeOut
     */
    public void setTimeOut(long timeOut) {
        this.timeOut = timeOut;
    }

    public long getTimeOut() {
        return timeOut;
    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    /**
     * 创建一个客户端
     *
     * @return
     */
    public FTPClient initFTPClient() {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setAutoNoopTimeout(timeOut);
        if (customPortRange) {
            System.setProperty("ftp4j.activeDataTransfer.hostAddress", ip);
            System.setProperty("ftp4j.activeDataTransfer.portRange", portRange);
        }
        ftpClient.setCharset(charset);
        try {
            //设置传输方式        自动选择 TYPE_AUTO = 0; 文件 TYPE_TEXTUAL = 1; 二进制流 TYPE_BINARY = 2;
            ftpClient.setType(type);
        } catch (Exception e) {
            ftpClient.setType(FTPClient.TYPE_BINARY);
        }
        try {
            //连接登录
            ftpClient.connect(ip, port);
            if (!anonymous) {
                ftpClient.login(user, password);
            } else {
                ftpClient.login("anonymous", "ftp4j");
            }
            if (!ftpClient.isConnected()) {
                ftpClient.disconnect(true);
                ftpClient = null;
            }
        } catch (Exception e) {
            ftpClient = null;
        }
        return ftpClient;
    }

    /**
     * 上传文件到指定文件夹
     *
     * @param dirsFtp
     * @param file
     * @return
     */
    public boolean uploadFile(String[] dirsFtp, File file) {
        return uploadFile(dirsFtp, file, null);
    }

    /**
     * 上传文件到指定文件夹
     *
     * @param dirsFtp          ftp 的文件夹  可以多个层级 会自动创建
     * @param file             上传的文件
     * @param transferListener 上传监听
     */
    public boolean uploadFile(String[] dirsFtp, File file, FTPDataTransferListener transferListener) {
        FTPClient ftpClient = initFTPClient();
        if (ftpClient == null) {
            return false;
        }
        try {
            //创建上传的目录
            // 这里目录要逐级创建
            // 重复创建会抛异常
            StringBuilder ftpPath = new StringBuilder();
            for (String dir : dirsFtp) {
                ftpPath.append("/").append(dir);
                try {
                    ftpClient.createDirectory(dir);
                } catch (Exception e) {
                }
                ftpClient.changeDirectory(dir);
            }
            //上传
            ftpClient.upload(file, transferListener);
            //关闭
            ftpClient.disconnect(true);
        } catch (Exception e) {
            return false;
        } finally {
            ftpClient = null;
        }
        return true;
    }

    public boolean downloadFile(String path, String fileName, File file) {
        return downloadFile(path, fileName, file, 0);
    }

    public boolean downloadFile(String path, String fileName, File file, long restartAt) {
        return downloadFile(path, fileName, file, restartAt, null);
    }

    /**
     * 下载指定文件
     *
     * @param path      ftp文件路径
     * @param fileName  ftp下载文件名称
     * @param file      写到本地的文件
     * @param restartAt 开始下载的长度 断点续传
     * @param listener  下载进度监听
     * @return
     */
    public boolean downloadFile(String path, String fileName, File file, long restartAt, FTPDataTransferListener listener) {
        FTPClient ftpClient = initFTPClient();
        try {
            //切换到当前目录
            ftpClient.changeDirectory(path);
            ftpClient.download(fileName, file, restartAt, listener);
        } catch (Exception e) {
            return false;
        } finally {
            ftpClient = null;
        }
        return true;
    }

}
